package 多线程.jol;


import org.openjdk.jol.info.ClassLayout;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;


public class Java内存布局 {
    static MyJavaObjectLayout objectLayout = new MyJavaObjectLayout();

    public static void main(String[] args) throws InterruptedException {
        ReentrantLock lock = new ReentrantLock();
        new Thread(() -> {
            try {
                lock.lock();
                try {
                    System.out.println(Thread.currentThread().getName()+" 拿到了锁");
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } finally {
                lock.unlock();
                System.out.println(Thread.currentThread().getName()+" 释放了所锁");
            }
        }, "t1").start();
        Thread.sleep(1000);
        Thread t2 = new Thread(() -> {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + " 拿到了锁");
                System.out.println(Thread.currentThread().getName() + ": " + Thread.interrupted());
            } finally {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + " 释放了所锁");
            }
        }, "t2");
        t2.start();


//        System.out.println(t2.isInterrupted());
    }

    private static void extracted1() {

    }

    private static void extracted() throws InterruptedException {
        MyLayout0 o = new MyLayout0();
        System.out.println(Thread.currentThread().getName() + "\t" + ClassLayout.parseInstance(o).toPrintable());
        Thread.sleep(5000);
        new Thread(() -> {
            synchronized (o) {
                System.out.println(Thread.currentThread().getName() + "\t" + ClassLayout.parseInstance(o).toPrintable());
            }
        }).start();
//        Thread.sleep(1000);
        System.out.println(Thread.currentThread().getName() + "\t" + ClassLayout.parseInstance(o).toPrintable());
    }

    private static void m1() {
        String s = ClassLayout.parseInstance(objectLayout).toPrintable();
        System.out.println(s);
        System.out.println("===================");
        MyLayout myLayout = new MyLayout();
        System.out.println(ClassLayout.parseInstance(myLayout).toPrintable());
        System.out.println("===================");
    }

    /**
     * 偏向所
     *
     * @throws InterruptedException
     */
    private static void m2() throws InterruptedException {
        Object o1 = new Object();
        System.out.println(ClassLayout.parseInstance(o1).toPrintable());
        Thread.sleep(5 * 1000);
        synchronized (o1) {
            System.out.println(ClassLayout.parseInstance(o1).toPrintable());
        }
    }

    /**
     * 先求hashCode,就没办法加偏向锁了,31为有值了,只能加轻量级锁
     *
     * @throws InterruptedException
     */
    private static void m3() throws InterruptedException {
        Thread.sleep(5 * 1000);
        Object o1 = new Object();
        System.out.println(o1.hashCode());
        System.out.println(ClassLayout.parseInstance(o1).toPrintable());
        synchronized (o1) {
            System.out.println(ClassLayout.parseInstance(o1).toPrintable());
        }
    }

    /**
     * 线加锁(加的为偏向锁,然后再求hashCode,由于线程id占用了hash的位置,所以会直接膨胀到重量级锁)
     *
     * @throws InterruptedException
     */
    private static void m4() throws InterruptedException {
        Thread.sleep(5 * 1000);
        Object o1 = new Object();
        synchronized (o1) {
            System.out.println(ClassLayout.parseInstance(o1).toPrintable());
            System.out.println(o1.hashCode());
            System.out.println(ClassLayout.parseInstance(o1).toPrintable());
        }
    }

    private static void m5() throws InterruptedException {
        Thread.sleep(5 * 1000);
        MyLayout myLayout = new MyLayout();
        System.out.println(Thread.currentThread().getName() + " start " + ClassLayout.parseInstance(myLayout).toPrintable());
        int count = 5;
        CountDownLatch countDownLatch = new CountDownLatch(count);
        for (int i = 0; i < count; i++) {
            new Thread(() -> {
//                System.out.println(Thread.currentThread().getName()+" start "+ClassLayout.parseInstance(myLayout).toPrintable());
                System.out.println(Thread.currentThread().getName() + " start " + ClassLayout.parseInstance(myLayout).toPrintable());
                for (int j = 0; j < 2; j++) {
                    myLayout.xxx();
                }
//                System.out.println(Thread.currentThread().getName());
                System.out.println(Thread.currentThread().getName() + " end " + ClassLayout.parseInstance(myLayout).toPrintable());
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + " end " + ClassLayout.parseInstance(myLayout).toPrintable());

    }
}

/**
 * 关闭指针压缩的参数: -XX:-UseCompressedOops
 * 开启指针压缩:引用类型占4byte,对象头4byte
 * 关闭指针压缩:引用类型占8byte,对象头8byte
 */
class MyLayout0 {

}

class MyLayout {
    String name;
    Integer height;
    int age;
    boolean isMarry;

    public synchronized void xxx() {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

